package sudoku_gameboard_structure;

import help_util.IndexConverter;
import sudoku_gui.SudokuComponentsProperties;
import sudoku_properties.BasicSudokuParam;

/*********************************************************************
 * Class SudokuGameboard
 * ~ Gameboard = 9x9 cells together as a game board
 * 1. perform and store parameters and functions
 *********************************************************************/
public class SudokuGameboard {

    public SudokuGameboard(){
        allCells = new Cell[NUM_CELLS_IN_UNIT][NUM_CELLS_IN_UNIT];
        for(int i=0; i<allCells.length; i++){
            for(int j=0; j<allCells[i].length; j++){
                allCells[i][j] = new Cell();
            }
        }
        NumOfUndefiniteCell = NUM_CELLS_IN_UNIT * NUM_CELLS_IN_UNIT;
    }

    public void setGivenCells(int[] inputGivenCellsIndex){

        final int[] GivenCellsIndex = inputGivenCellsIndex;

        for( int i = 0 ; i < GivenCellsIndex.length ; i++ )
        {
            final int INDEX_X = IndexConverter.getHorizontalIndex(GivenCellsIndex[i]) ;
            final int INDEX_Y = IndexConverter.getVerticalIndex(GivenCellsIndex[i]) ;
            allCells[INDEX_X][INDEX_Y].setIsGiven(SudokuComponentsProperties.getIsTrue());
        }
    }
    
    public boolean isGivenCells(int indexX, int indexY){
        return allCells[indexX][indexY].isGiven();
    }

    /* For given Cells*/
    public void setDefiniteCellsValue(int[] inputCellsIndex, int inputCellValue){

        final int CellValue = inputCellValue;
        final int[] CellsIndex = inputCellsIndex;
        for( int i = 0 ; i < CellsIndex.length ; ++i )
        {
            final int INDEX_X = IndexConverter.getHorizontalIndex(CellsIndex[i]) ;
            final int INDEX_Y = IndexConverter.getVerticalIndex(CellsIndex[i]) ;
            for(int j=0; j<NUM_CELLS_IN_UNIT; j++){
                if( CellValue != j+1){
                    allCells[INDEX_X][INDEX_Y].setImpossValue(j+1);
                }
            }
        }
    }
    /* For Sudoku UI */
    public void setPossCellsValue(int inputCellsIndex, int inputCellValue){

        final int CellValue = inputCellValue;
        final int CellsIndex = inputCellsIndex;
        final int INDEX_X = IndexConverter.getHorizontalIndex(CellsIndex);
        final int INDEX_Y = IndexConverter.getVerticalIndex(CellsIndex) ;
        allCells[INDEX_X][INDEX_Y].setPossValue(CellValue);
    }
    public void setImpossCellsValue(int inputCellsIndex, int inputCellValue){

        final int CellValue = inputCellValue;
        final int CellsIndex = inputCellsIndex;
        final int INDEX_X = IndexConverter.getHorizontalIndex(CellsIndex);
        final int INDEX_Y = IndexConverter.getVerticalIndex(CellsIndex) ;
        allCells[INDEX_X][INDEX_Y].setImpossValue(CellValue);
    }


    /* return true if cell value is possible */
    public boolean isPossCellValue(int indexX, int indexY, int checkValue){
        return allCells[indexX][indexY].isPossValue(checkValue);
    }

    /* return the definiate value of the cells */
    /* return 0 if no value set */
    public int getDefiniteCellValue(int inputIndexX, int inputIndexY){
        int cellValue = 0;
        int indexX = inputIndexX;
        int indexY = inputIndexY;
        int[] possValue = allCells[indexX][indexY].getPossibleValues();
        /* only one possible value*/
        if(possValue.length == 1){
            /* cellValue from 1=9, possValue  from 0-8*/
            cellValue = possValue[0];
        }
        return cellValue;
    }

    /* set cell value */
    public void setCellValue(int inputIndexX, int inputIndexY, int inputCellValue){
        allCells[inputIndexX][inputIndexY].setCellValue(inputCellValue);
    }
    /* get cell value */
    public int getCellValue(int indexX, int indexY){
        return allCells[indexX][indexY].getCellValue();
    }

    /* check cell is correct */
    public boolean isCorrectCell(int indexX, int indexY){
        return allCells[indexX][indexY].isCorrectCell();
    }
    public void setCorrectCell(int indexX, int indexY, boolean isCorrect){
        allCells[indexX][indexY].setIsCorrectCell(isCorrect);
    }

    /* lcoal variables */
    private int NUM_CELLS_IN_UNIT = BasicSudokuParam.getNumCellsInUnit();
    private Cell[][] allCells;
    private int NumOfUndefiniteCell;

}
